#ifndef __GE_MATERIAL_H__
#define __GE_MATERIAL_H__

#include "GE_Base.h"
namespace Syp
{
///A SubMaterial contains details/description of a material. Each Material may have many SubMaterials.
struct SYPAPI SubMaterial
{
	friend class Renderer;
	SubMaterial(const SubMaterial& sm);
	SubMaterial& operator=(const SubMaterial& sm);
	SubMaterial();
	~SubMaterial();
	float diffuse[4];
	float ambient[4];
	float specular[4];
	float shininess;
	///Type of blending to use for material. Default is NOBLEND. 
	BlendType btype;
	///Toggles whether this material is lit by lighting. This variable basically means whether the lights around it will have any effect on the material. While it is rarely to be used, i just thought it could produce some cool effects in a non-realistic setting if used by a creative person. 1 example is where your backdrop/scene is realistically lit by lighting, but your characters are cartoon like and visible all the time. And also useful for GUI. When a object is not lit, it's color is defined by the ambient value.
	bool lit;
	void useTexture(TextureObj* txtID);
	void useTexture(const String& filename);
	///Name of the effect to be used by this submaterial. Currently calls to useEffect will not affect MeshInstances already added in SceneManager. 
	void useEffect(const String& e);
	///Returns a pointer to the effect being used by this submaterial. Note: Currently. changes(Insertion/removal of passes) made to effects after startup will not be relflected. 
	Effect* getEffect();
	///Returns a pointer to the current TextureObj in use.
	TextureObj* getTexture();
	///Clears the texture being used by the MeshInstance.
	void clearTexture();
	

private:
	///The effect currently being used by the SubMaterial
	Effect* effect;
	///Uses the defined Effect for this submaterial.
	void useEffect(Effect* e);
	///Texture filename reccommendation. 
	TextureObj* diffuseMap;
	void copy(const SubMaterial& sm);
	
};


///A Material describes how a particular mesh interacts with the lights. Material Objects are automatically managed and cannot be deleted explictly by the user. 
class SYPAPI Material : public Resource
{
public:	
	///Filename refers to the filename of the Material. Generally if your Material is loaded from the file, you should not call this method. Use the loadFromFile(const String& fileName) method. This method is used for Materials not loaded from file but in code.
	static Material* createMaterial(const String& filename);
	static void destroyMaterial(Material* m);
		
	std::vector<SubMaterial> subMaterials;

	static Material* loadFromFile(const String& fileName);
private:
	Material(const String& filename);	
	~Material(){};
	///NOT FOR CLIENT USE adds an instance to its list. This method is unsafe to be called by the user. Use MeshInstance.useMesh()/clearMesh() instead.
	friend void MeshInstance::useMaterial(Material* m);
	friend void MeshInstance::clearMaterial();
};


}
#endif //__GE_MATERIAL_H__

